package org.example.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.example.dto.Doctor;
import org.example.manage.DoctorManage;
import org.example.mapper.DoctorMapper;
import org.example.service.DoctorService;
import org.example.util.JSONUtil;
import org.springframework.http.HttpRequest;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DoctorServiceImpl implements DoctorService {
    private final String PREFIX_KEY = "cache:doctor:";

    @Resource
    private DoctorManage doctorManage;

    @Resource
    private DoctorMapper doctorMapper;

    private BloomFilter filter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()),10000,0.1);




    //每天凌晨2点自动操作该方法
    @Override
    @Scheduled(cron = "0 12 11 * * ?")
    public void addData() {
        Map<String,Doctor> map = new HashMap<>();
        //1.查询数据库中所有的数据
        List<Doctor> doctors = doctorMapper.queryDoctor();

        //2.删除缓存中的数据
        if(doctors  != null){
            List<String> keys = new ArrayList<>();
            for(Doctor doctor : doctors){
                keys.add(PREFIX_KEY + doctor.getDoctorId());
                //在循环的时候把结果添加到map中
                map.put(PREFIX_KEY + doctor.getDoctorId(),doctor);
                //添加进bloomfilter
               filter.put(doctor.getDoctorId());
            }
            doctorManage.deleteCacheAll(keys);
        }
        //3.把查询出来的结果添加到缓存中
            doctorManage.addDoctor(map);

        //4.输出OK，要求必须是结束后输出OK
            log.debug("===========数据缓存完毕==============");

    }

    @Override
    public Doctor queryDoctor(String id) throws JsonProcessingException {
        //先不走缓存，先判断bloomfilter
        boolean b = filter.mightContain(id);
        if(b) {
            //先走缓存，如果缓存没有才走数据库，同时走完数据后在把结果更新到缓存中
            Doctor doctorStr = doctorManage.queryDoctor(PREFIX_KEY + id);
            if (doctorStr != null) {
//            doctorStr =  doctorStr.replace("\"@class\": \"org.example.dto.Doctor\",","");
//            System.out.println(doctorStr);
//            Doctor doctor =(Doctor) JSONUtil.str2obj(doctorStr);
                return doctorStr;
            }
            Doctor doctor = doctorMapper.queryDoctorById(id);
            Map<String, Doctor> map = new HashMap<>();
            map.put(PREFIX_KEY + doctor.getDoctorId(), doctor);
            doctorManage.addDoctor(map);
            return doctor;
        }else{
            return null;
        }
    }

    @Override
    public List<String> getId() {
        List<Doctor> doctors = doctorMapper.queryDoctor();
        List<String> ids = new ArrayList<>();
        for(Doctor doctor : doctors){
            ids.add(doctor.getDoctorId());
        }
        return ids;
    }
}
